package org.itboys.weixin;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.ibatis.annotations.Param;
import org.itboys.baseobject.entity.City;
import org.itboys.baseobject.service.CityService;
import org.itboys.commons.CommonConstants;
import org.itboys.commons.dto.ResultPageDOHelper;
import org.itboys.commons.utils.ajax.AjaxUtils;
import org.itboys.commons.utils.random.RandomUtils;
import org.itboys.framework.resource.ResourceHolder;
import org.itboys.framework.spring.controller.BaseController;
import org.itboys.fuzion.entity.FuzionMember;
import org.itboys.fuzion.service.FuzionMemberService;
import org.itboys.manager.OrderMemberService;
import org.itboys.pay.weixin.WXPayService;
import org.itboys.pay.weixin.WeixinOrderQuery;
import org.itboys.pay.weixin.WeixinPaySignTool;
import org.itboys.product.constant.ProductConstant;
import org.itboys.product.entity.Order;
import org.itboys.product.entity.Product;
import org.itboys.product.service.OrderService;
import org.itboys.product.service.ProductService;
import org.itboys.weixin.entity.WeixinConfig;
import org.itboys.weixin.service.WeixinConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.google.common.collect.Maps;

/**
 * Created by huml on 2016/4/19.
 * 微信订单业务
 */
@RestController
@RequestMapping("/weixin/order")
public class OrderWeixinController extends BaseController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private ProductService productService;
    @Autowired
    private CityService cityService;
    @Autowired
    private WeixinConfigService weixinConfigService;
    @Autowired
    private OrderMemberService orderMemberService;
    @Autowired
    private FuzionMemberService memberService;

    @RequestMapping("/testOrder")
    public void testOrder(HttpServletRequest request,HttpServletResponse response){
    	AjaxUtils.renderText(response, CommonConstants.FAIL);
    }

    /**
     * 购买页面
     * @return
     */
    @RequestMapping("/buyProductVM")
    public ModelAndView buyProductVM(@RequestParam("productId")Long productId, Model model){
        Product product = productService.getById(productId);
        model.addAttribute("product", product);
        return new ModelAndView("site/buyProduct");
    }

    /**
     * 购买生成订单
     * @param name  收货人
     * @param mobile  联系电话
     * @param districtId  区县
     * @param address  详细地址
     * @param postcode  邮编
     * @param productId  产品id
     * @param payMethod  支付方式
     * @param response
     * @return
     */
    @RequestMapping("/buyProduct")
    public void buyProduct(@RequestParam("name")String name,
                                   @RequestParam("mobile")String mobile,
                                   @RequestParam("districtId")Long districtId,
                                   @RequestParam("address")String address,
                                   @RequestParam("postcode")String postcode,
                                   @RequestParam("productId")Long productId,
                                   @RequestParam("payMethod")Integer payMethod,
                                   HttpServletRequest request,
                                   HttpServletResponse response){
       try {
           FuzionMember member = (FuzionMember) request.getSession().getAttribute("member");
           City city = cityService.getById(districtId);
           address = city.getMergerName() + address;
           Order order = orderService.createOrder(member.getId(),productId,1,payMethod,address, name, mobile, postcode);
           if(order == null){
               AjaxUtils.renderText(response, "库存不足");
               return;
           }
           Object object = orderService.payOrder(order.getId(), request);
           if(object instanceof Long || object instanceof Integer){//说明是能量豆支付
               AjaxUtils.renderText(response, String.valueOf(object));
           } else {
               WeixinPaySignTool weixinPaySignTool = (WeixinPaySignTool)object;
               Map<String, Object> map = Maps.newHashMapWithExpectedSize(2);
               map.put("weixinPaySignTool", weixinPaySignTool);
               map.put("order", order);
               AjaxUtils.renderJson(response, map);
           }
       } catch (Exception e) {
           logger.error("/weixin/order/buyProduct error", e);
           AjaxUtils.renderText(response, CommonConstants.FAIL);
       }
    }

    /**
     * 跳转能量豆购买页面
      * @return
     */
    @RequestMapping("/toBean")
    public ModelAndView toBean(HttpServletRequest request, HttpServletResponse response){
        return new ModelAndView("site/productEnergyBean");
    }

    /**
     * 购买能量豆
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/buyBean")
    public void buyBean(HttpServletRequest request,
                                HttpServletResponse response){
        Order order = null;
        try {
            FuzionMember member = (FuzionMember) request.getSession().getAttribute("member");
            order = orderService.buyBean(member);
            if(order == null){
                AjaxUtils.renderText(response, "1");
                return;
            }
            Object object = orderService.payOrder(order.getId(), request);
            String weixinPaySignTool = (String)object;
            Map<String, Object> map = Maps.newHashMapWithExpectedSize(2);
            map.put("weixinPaySignTool", weixinPaySignTool);
            map.put("order", order);
            AjaxUtils.renderJson(response, map);
        } catch (Exception e) {
            if(order != null){
                orderService.delete(order.getId());
            }
            logger.error("/weixin/order/buyBean error", e);
            AjaxUtils.renderText(response, CommonConstants.FAIL);
        }
    }
    
    

    /**
     * 支付   能量豆的话直接支付  微信的话先下单签名
     * @param orderId
     * @param request
     * @param response
     */
    @RequestMapping("/doPay")
    public void doPay(@RequestParam("orderId")Long orderId,
                      HttpServletRequest request,
                      HttpServletResponse response){
        try {
            Order order = orderService.getById(orderId);
            order.setOrderNo(System.currentTimeMillis() + RandomUtils.getIntRandom(6));
            orderService.update(order);
            Object object = orderService.payOrder(orderId, request);
            if(object instanceof Integer){//说明是能量豆支付
                AjaxUtils.renderText(response, String.valueOf(object));
            } else {
                String weixinPaySignTool = (String)object;
                Map<String, Object> map = Maps.newHashMapWithExpectedSize(2);
                map.put("weixinPaySignTool", weixinPaySignTool);
                map.put("order", order);
                AjaxUtils.renderJson(response, map);
            }
        } catch (Exception e) {
            logger.error("/weixin/order/doPay error", e);
            AjaxUtils.renderText(response, CommonConstants.FAIL);
        }
    }

    /**
     * 支付成功页面
     * @param orderId
     * @param model
     * @return
     */
    @RequestMapping("/paySuccess")
    public ModelAndView paySuccess(@RequestParam("orderId")Long orderId, Model model){
        model.addAttribute("order", orderService.getById(orderId));
        return new ModelAndView("site/paySuccess");
    }

    /**
     * 微信支付异步回调
     * @param request
     * @param response
     */
    @RequestMapping("/weixinNotify/{orderNo}")
    public void weixinNotify(HttpServletRequest request,
                             @PathVariable("orderNo")String orderNo,
                             HttpServletResponse response){
        try {
            String result = orderMemberService.weixinNotify(request, orderNo);
            logger.info("****************weixinNotify result*************" + result);
            AjaxUtils.renderText(response, result);
        } catch (Exception e) {
            logger.error("/weixin/order/weixinNotify error", e);
            AjaxUtils.renderText(response, CommonConstants.FAIL);
        }
    }

    /**
     * 查询订单状态
     */
    @RequestMapping("/weixinOrderQuery")
    public void weixinOrderQuery(HttpServletRequest request,
                                 @RequestParam("orderNo")String orderNo,
                                 HttpServletResponse response){
        try {
            FuzionMember member = (FuzionMember) request.getSession().getAttribute("member");
            WeixinConfig weixinConfig = weixinConfigService.getById(Long.valueOf(member.getWeixinId()));
            String state = WXPayService.orderQuery(orderNo, weixinConfig.getAppId(), weixinConfig.getPartnerId(), weixinConfig.getPartnerKey());
            if(state.equals(WeixinOrderQuery.SUCCESS)){
                //支付成功
                AjaxUtils.renderText(response, CommonConstants.SUCCESS);
            } else {
                AjaxUtils.renderText(response, CommonConstants.FAIL);
            }
        } catch (Exception e) {
            logger.error("/weixin/order/weixinOrderQuery error", e);
            AjaxUtils.renderText(response, CommonConstants.FAIL);
        }
    }

    /**
     * 我的订单
     * @param model
     * @param request
     * @return
     */
    @RequestMapping("/myOrderFirstpage")
    public ModelAndView myOrderFirstpage(Model model,
                                @RequestParam("rows")Integer rows,
                                @RequestParam("status")Integer status,
                                HttpServletRequest request){
        Long memberId = (Long) request.getSession().getAttribute("memberId");
        if(memberId == null){
            return new ModelAndView("error");
        }
        List<Order> list = orderService.myOrderFirstPage(rows, status, memberId);
        for (Order order :
                list) {
            BigDecimal price = new BigDecimal(order.getTotalFee()).divide(new BigDecimal(100));
            order.setViewFee(price.toString());
        }
        model.addAttribute("orders", list);
        model.addAttribute("status", status);
        model.addAttribute("type", "1");
        return new ModelAndView("site/myOrder1");
    }

    /**
     * 分页获取我的订单
     * @param request
     * @param response
     * @param status
     */
    @RequestMapping("/myOrder")
    public void myOrder(HttpServletRequest request, HttpServletResponse response,
                        @Param("callback")String callback,
                        @RequestParam("status")Integer status){
        try{
            Long memberId = (Long) request.getSession().getAttribute("memberId");
            if(memberId == null){
                AjaxUtils.renderJsonporJson(response, null, ResultPageDOHelper.getErrorResultDO(-1, CommonConstants.FAIL));
                return;
            }
            List<Order> orders = orderService.myOrder(memberId, status, request);
            for (Order order :
                    orders) {
                BigDecimal price = new BigDecimal(order.getTotalFee()).divide(new BigDecimal(100));
                order.setViewFee(price.toString());
            }
            AjaxUtils.renderJsonporJson(response, callback, ResultPageDOHelper.getMsgResultDO(orders, CommonConstants.SUCCESS));
        } catch (Exception e){
            logger.error("/weixin/order/myOrder error", e);
            AjaxUtils.renderJsonporJson(response, callback, ResultPageDOHelper.getErrorResultDO(-1, CommonConstants.FAIL));
        }
    }

    /**
     * 取消订单
     * @param orderId
     * @param callback
     * @param response
     */
    @RequestMapping("/cancelOrder")
    public void cancelOrder(@RequestParam("orderId")Long orderId,
                            @Param("callback")String callback,
                            HttpServletResponse response){
        try{
            Order order = orderService.getById(orderId);
            if(order != null && order.getStatus().equals(ProductConstant.OrderStatic.ORDER_STATUS_CREATE)){//只有待付款的订单才能取消
                order.setStatus(ProductConstant.OrderStatic.ORDER_STATUS_CANCLE);
                order.setCancelTime(new Date());
                orderService.update(order);
                if(order.getProductId() > 0){
                    Product product = productService.getById(order.getProductId());
                    product.setProductStore(product.getProductStore() + 1);
                    productService.update(product);
                }
            }
            AjaxUtils.renderJsonporJson(response, callback, ResultPageDOHelper.getMsgCodeResultDO(0, CommonConstants.SUCCESS));
        } catch (Exception e){
            logger.error("/weixin/order/cancelOrder error", e);
            AjaxUtils.renderJsonporJson(response, callback, ResultPageDOHelper.getErrorResultDO(-1, CommonConstants.FAIL));
        }
    }

    /**
     * 删除订单
     * @param orderId
     * @param response
     */
    @RequestMapping("/deleteOrder")
    public void deleteOrder(@RequestParam("orderId")Long orderId,
                            HttpServletResponse response){
        try{
            Order order = orderService.getById(orderId);
            if(order != null && (order.getStatus().equals(ProductConstant.OrderStatic.ORDER_STATUS_SUCCESS) || order.getStatus().equals(ProductConstant.OrderStatic.ORDER_STATUS_LOSE_SUCCESS)
                    || order.getStatus().equals(ProductConstant.OrderStatic.ORDER_STATUS_DELETE))){//只有待付款的订单才能取消
                order.setIsDeleted(1);
                orderService.update(order);
            }
            AjaxUtils.renderJsonporJson(response, null, ResultPageDOHelper.getMsgCodeResultDO(0, CommonConstants.SUCCESS));
        } catch (Exception e){
            logger.error("/weixin/order/deleteOrder error", e);
            AjaxUtils.renderJsonporJson(response, null, ResultPageDOHelper.getErrorResultDO(-1, CommonConstants.FAIL));
        }
    }
    @RequestMapping("/test")
    public void test(){
        final List<FuzionMember> members = memberService.list(Maps.newHashMapWithExpectedSize(0));
        logger.info("::::::::::::::::::::::::::::::::::::::::::::::::::::"+members.size());
        for (int i = 0; i < 100; i++) {
            final int k = i;
            ExecutorService fixedThreadPool = Executors.newSingleThreadExecutor();//开个线程推送  单线程
            fixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        int j = k;
                        if(k >= members.size()){
                           j = k % members.size();
                        }
                        FuzionMember member = members.get(j);
                        if(member.getId() > 1){
                            Order order = orderService.buyBean(member);
                            order.setStatus(ProductConstant.OrderStatic.ORDER_STATUS_PAY);
                            orderService.update(order);
                            String result = orderMemberService.weixinNotify1(order.getOrderNo());
                            logger.info("************result*****************"+result);
                        }
                    } catch (Exception e) {
                        logger.error("push dynamic error", e);
                    }
                }
            });
        }
    }

}
